/* **********************************************************************

 Licensed Materials - Property of IBM

 5724-U69

 Copyright IBM Corp. 2008  All Rights Reserved.
 */
package com.ibm.ecm.configmgr.app.acm.widgets.rest;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
//import javax.servlet.http.HttpServlet;

public class MashupMakerProxy{
    @SuppressWarnings("unused")
    //private final static String COPYRIGHT        = com.ibm.mm.test.rest.Copyright.SHORT;

    private static final long   serialVersionUID = 1L;

    private static void configSSL(final HttpsURLConnection httpsConnection) {
        httpsConnection.setHostnameVerifier(new HostnameVerifier() {
            public boolean verify(final String hostname, final SSLSession sslSession) {
                return true;
            }
        });
        final javax.net.ssl.X509TrustManager xtm = new javax.net.ssl.X509TrustManager() {

            public void checkClientTrusted(final X509Certificate[] chain, final String authType)
                    throws CertificateException {
            }

            public void checkServerTrusted(final X509Certificate[] chain, final String authType)
                    throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

        };

        final javax.net.ssl.TrustManager mytm[] = { xtm };
        javax.net.ssl.SSLContext ctx;
        try {
            ctx = javax.net.ssl.SSLContext.getInstance("SSL");
            ctx.init(null, mytm, null);
            final javax.net.ssl.SSLSocketFactory sf = ctx.getSocketFactory();
            httpsConnection.setSSLSocketFactory(sf);
        } catch (final NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        } catch (final KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    private static void extractCookie(final HttpURLConnection connection, final Map<String, String> cookies) {
        final Map<String, List<String>> headers = connection.getHeaderFields();
        final List<String> setCookies = headers.get("Set-Cookie");
        if (setCookies != null) {
            for (String cookie : setCookies) {
                if (cookie.indexOf(";") != -1) {
                    cookie = cookie.substring(0, cookie.indexOf(";"));
                    final int index = cookie.indexOf('=');
                    if (index != -1) {
                        final String cookieName = cookie.substring(0, index);
                        final String cookieValue = cookie.substring(index + 1);
                        cookies.put(cookieName, cookieValue);
                    }
                }
            }
        }

    }

    private static HttpURLConnection getURLConnection(final String urlString) throws IOException {

        final URL url = new URL(urlString);
        final HttpURLConnection connection = (HttpURLConnection) url.openConnection();

        if (connection instanceof HttpsURLConnection) {
            MashupMakerProxy.configSSL((HttpsURLConnection) connection);
        }

        connection.setDefaultUseCaches(false);
        connection.setUseCaches(false);
        connection.setReadTimeout(100000);
        final java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z",
                java.util.Locale.US);
        format.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
        final String date = format.format(new java.util.Date());
        connection.setRequestProperty("Date", date);

        return connection;

    }

    public static Map<String, String> loginMashupMaker(final String url, final String username, final String password)
            throws IOException {
        final Map<String, String> cookies = new HashMap<String, String>();
        HttpURLConnection connection = null;
        String location = null;

        // get the login form
        try {
            connection = MashupMakerProxy.getURLConnection(url);
            connection.setRequestMethod("GET");
            connection.setInstanceFollowRedirects(false);

            MashupMakerProxy.extractCookie(connection, cookies);
            location = connection.getHeaderField("Location");

        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        // get the login page
        try {
            if (location != null) {
                connection = MashupMakerProxy.getURLConnection(location);
                connection.setRequestMethod("GET");
                connection.setInstanceFollowRedirects(false);
                MashupMakerProxy.extractCookie(connection, cookies);
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        // login
        try {
            String login_url = location;
            final int index = location.lastIndexOf('/');
            login_url = login_url.substring(0, index);
            connection = MashupMakerProxy.getURLConnection(login_url + "/j_security_check");
            connection.setRequestMethod("POST");
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setInstanceFollowRedirects(false);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestProperty("Cookie", MashupMakerProxy.toCookieString(cookies));
            final PrintWriter output = new PrintWriter(new OutputStreamWriter(connection.getOutputStream()));
            output.print("j_username=");
            output.print(username);
            output.print("&");
            output.print("j_password=");
            output.print(password);
            output.flush();

            final int status = connection.getResponseCode();
            location = connection.getHeaderField("Location");
            MashupMakerProxy.extractCookie(connection, cookies);
            connection.disconnect();
            if ((status == 302) && (location.indexOf("bootstrap") != -1)) {
                return null;// login fail
            } else {
                return cookies;
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    private static String toCookieString(final Map<String, String> cookies) {
        final StringWriter sw = new StringWriter();
        for (final String name : cookies.keySet()) {
            sw.write(name);
            sw.write("=");
            sw.write(cookies.get(name));
            sw.write(";");
        }
        String result = sw.toString();
        if (result.endsWith(";")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }
}
